#include <QDebug>
#include "DefaultLexer.h"
#include <Qsci/qsciscintilla.h>

namespace Lexers{

DefaultLexer::DefaultLexer(QObject *parent):
    QsciLexerCustom(parent)
{
    setColor(Qt::black, Default);
    setColor(Qt::blue, DoubleQuotedString);
    setColor(Qt::blue, SingleQuotedString);
    setColor(Qt::green, Number);
}

DefaultLexer::~DefaultLexer()
{
    //qDebug() << "remove default lexer";
}

QsciLexer * DefaultLexer::lexer()
{
    return this;
}

void DefaultLexer::setTheme(ITheme *)
{

}

QList<int> DefaultLexer::styles()
{
    QList<int> styles;
    styles << Default << DoubleQuotedString << SingleQuotedString << Number;
    return styles;
}

const char* DefaultLexer::language() const
{
    return "generic";
}

QString DefaultLexer::description(int style) const
{
    switch(style){
    case Default: return tr("Default");
    case DoubleQuotedString: return tr("Double quoted string");
    case SingleQuotedString: return tr("Single quoted string");
    case Number: return tr("Number");
    }
    return "";
}

QString DefaultLexer::nameInTheme(int style) const
{
    switch(style){
    case Default: return "default";
    case DoubleQuotedString: return "dString";
    case SingleQuotedString: return "sString";
    case Number: return "number";
    }
    return "";
}

void DefaultLexer::styleText(int start, int end)
{
    if (!editor())
        return;

    char * text = new char[end - start + 1];
    editor()->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE, start, end, text);
    startStyling(start, 0x1f);

    int style = editor()->SendScintilla(QsciScintilla::SCI_GETSTYLEAT, start-1);
    pushStyle(start, Default);
    if (style)
        pushStyle(start, style);

    for(int i = start; i < end; ++i){
        if (text[i-start] == '"' || style == DoubleQuotedString){
            if (style != DoubleQuotedString){
                pushStyle(i, DoubleQuotedString);
            }
            for(int j = i+1; j < end; ++j){
                if (text[j-start] == '"'){
                    if (style)
                        style = 0;
                    popStyle(j+1, DoubleQuotedString);
                    i = j+1;
                    break;
                }
            }
        }
        if (text[i-start] == '\'' || style == SingleQuotedString){
            if (style != SingleQuotedString){
                pushStyle(i, SingleQuotedString);
            }
            for(int j = i+1; j < end; ++j){
                if (text[j-start] == '\''){
                    if (style)
                        style = 0;
                    popStyle(j+1, SingleQuotedString);
                    i = j+1;
                    break;
                }
            }
        }

        if ((isdigit(text[i-start]) || (i < end && text[i-start] == '.' && isdigit(text[i-start+1]))) && (i-start > 0 && !isalpha(text[i-start-1]))){
            pushStyle(i, Number);
            for(int j = i+1; j < end; j++){
                if (!(isdigit(text[j-start]) || text[j-start] == '.')){
                    popStyle(j, Number);
                    i = j;
                    break;
                }
            }
        }
    }
    _stylesMap.clear();
    delete [] text;
}



void DefaultLexer::pushStyle(int pos, int style)
{
    if (_stylesMap.length() > 0){
        setStyling(pos - _stylesMap.last().start, _stylesMap.last().style);
    }
    _stylesMap.append(StyleStruct(pos, style));
}

void DefaultLexer::popStyle(int pos, int /*style*/)
{
    StyleStruct st = _stylesMap.takeLast();
    setStyling(pos - st.start, st.style);
    _stylesMap.last().start = pos;
}

QString DefaultLexer::name()
{
    return "Default";
}

QColor DefaultLexer::color(int style)
{
    return defaultColor(style);
}

}
